<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>Vue知识点总结 | MyBlog</title>
    <meta name="generator" content="VuePress 1.8.2">
    <link rel="icon" href="/markdown-blog/favicon.ico">
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
    
    <link rel="preload" href="/markdown-blog/assets/css/0.styles.25640b18.css" as="style"><link rel="preload" href="/markdown-blog/assets/js/app.4ad08097.js" as="script"><link rel="preload" href="/markdown-blog/assets/js/3.ddd67056.js" as="script"><link rel="preload" href="/markdown-blog/assets/js/1.7a25059f.js" as="script"><link rel="preload" href="/markdown-blog/assets/js/31.3a6f1d19.js" as="script"><link rel="prefetch" href="/markdown-blog/assets/js/10.f00be53f.js"><link rel="prefetch" href="/markdown-blog/assets/js/11.7ac2e99b.js"><link rel="prefetch" href="/markdown-blog/assets/js/12.f11c009c.js"><link rel="prefetch" href="/markdown-blog/assets/js/13.be750ad0.js"><link rel="prefetch" href="/markdown-blog/assets/js/14.09d576e3.js"><link rel="prefetch" href="/markdown-blog/assets/js/15.b4c1727e.js"><link rel="prefetch" href="/markdown-blog/assets/js/16.4890e6f7.js"><link rel="prefetch" href="/markdown-blog/assets/js/17.feac5f26.js"><link rel="prefetch" href="/markdown-blog/assets/js/18.b49467b1.js"><link rel="prefetch" href="/markdown-blog/assets/js/19.29b4407f.js"><link rel="prefetch" href="/markdown-blog/assets/js/20.9ee55973.js"><link rel="prefetch" href="/markdown-blog/assets/js/21.b6da110b.js"><link rel="prefetch" href="/markdown-blog/assets/js/22.c64d89ab.js"><link rel="prefetch" href="/markdown-blog/assets/js/23.1249a0d2.js"><link rel="prefetch" href="/markdown-blog/assets/js/24.858426bc.js"><link rel="prefetch" href="/markdown-blog/assets/js/25.1eaccce9.js"><link rel="prefetch" href="/markdown-blog/assets/js/26.6d8a66e7.js"><link rel="prefetch" href="/markdown-blog/assets/js/27.bef6e2f6.js"><link rel="prefetch" href="/markdown-blog/assets/js/28.1d169f61.js"><link rel="prefetch" href="/markdown-blog/assets/js/29.f6bd6a28.js"><link rel="prefetch" href="/markdown-blog/assets/js/30.6b0a16e0.js"><link rel="prefetch" href="/markdown-blog/assets/js/4.46f777c5.js"><link rel="prefetch" href="/markdown-blog/assets/js/5.db5e4405.js"><link rel="prefetch" href="/markdown-blog/assets/js/6.8b37b343.js"><link rel="prefetch" href="/markdown-blog/assets/js/7.cacb4248.js"><link rel="prefetch" href="/markdown-blog/assets/js/8.6174f008.js"><link rel="prefetch" href="/markdown-blog/assets/js/9.4f9a61ea.js">
    <link rel="stylesheet" href="/markdown-blog/assets/css/0.styles.25640b18.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container" data-v-1aefc0b4><div data-v-1aefc0b4><div id="loader-wrapper" class="loading-wrapper" data-v-d48f4d20 data-v-1aefc0b4 data-v-1aefc0b4><div class="loader-main" data-v-d48f4d20><div data-v-d48f4d20></div><div data-v-d48f4d20></div><div data-v-d48f4d20></div><div data-v-d48f4d20></div></div> <!----> <!----></div> <div class="password-shadow password-wrapper-out" style="display:none;" data-v-25ba6db2 data-v-1aefc0b4 data-v-1aefc0b4><h3 class="title" data-v-25ba6db2 data-v-25ba6db2>MyBlog</h3> <p class="description" data-v-25ba6db2 data-v-25ba6db2></p> <label id="box" class="inputBox" data-v-25ba6db2 data-v-25ba6db2><input type="password" value="" data-v-25ba6db2> <span data-v-25ba6db2>Konck! Knock!</span> <button data-v-25ba6db2>OK</button></label> <div class="footer" data-v-25ba6db2 data-v-25ba6db2><span data-v-25ba6db2><i class="iconfont reco-theme" data-v-25ba6db2></i> <a target="blank" href="https://vuepress-theme-reco.recoluan.com" data-v-25ba6db2>vuePress-theme-reco</a></span> <span data-v-25ba6db2><i class="iconfont reco-copyright" data-v-25ba6db2></i> <a data-v-25ba6db2><span data-v-25ba6db2>kasnars</span>
            
          <span data-v-25ba6db2>2021 - </span>
          2024
        </a></span></div></div> <div class="hide" data-v-1aefc0b4><header class="navbar" data-v-1aefc0b4><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/markdown-blog/" class="home-link router-link-active"><img src="/markdown-blog/wsq.webp" alt="MyBlog" class="logo"> <span class="site-name">MyBlog</span></a> <div class="links"><div class="color-picker"><a class="color-button"><i class="iconfont reco-color"></i></a> <div class="color-picker-menu" style="display:none;"><div class="mode-options"><h4 class="title">Choose mode</h4> <ul class="color-mode-options"><li class="dark">dark</li><li class="auto active">auto</li><li class="light">light</li></ul></div></div></div> <div class="search-box"><i class="iconfont reco-search"></i> <input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/markdown-blog/" class="nav-link"><i class="iconfont reco-home"></i>
  主页
</a></div><div class="nav-item"><a href="/markdown-blog/timeline/" class="nav-link"><i class="iconfont reco-date"></i>
  时间轴
</a></div><div class="nav-item"><a href="/markdown-blog/tag/" class="nav-link"><i class="iconfont reco-tag"></i>
  标签
</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title"><i class="iconfont reco-message"></i>
      文档
    </span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/markdown-blog/docs/theme-reco/" class="nav-link router-link-active"><i class="undefined"></i>
  前端知识点
</a></li><li class="dropdown-item"><!----> <a href="/markdown-blog/docs/computer/" class="nav-link"><i class="undefined"></i>
  计算机基础
</a></li><li class="dropdown-item"><!----> <a href="/markdown-blog/docs/others/" class="nav-link"><i class="undefined"></i>
  其他技术栈
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title"><i class="iconfont reco-category"></i>
      分类
    </span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/markdown-blog/categories/个人作品/" class="nav-link"><i class="undefined"></i>
  个人作品
</a></li><li class="dropdown-item"><!----> <a href="/markdown-blog/categories/解决方案/" class="nav-link"><i class="undefined"></i>
  解决方案
</a></li><li class="dropdown-item"><!----> <a href="/markdown-blog/categories/BUG记录/" class="nav-link"><i class="undefined"></i>
  BUG记录
</a></li><li class="dropdown-item"><!----> <a href="/markdown-blog/categories/技术整理/" class="nav-link"><i class="undefined"></i>
  技术整理
</a></li><li class="dropdown-item"><!----> <a href="/markdown-blog/categories/前端总结/" class="nav-link"><i class="undefined"></i>
  前端总结
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title"><i class="iconfont reco-message"></i>
      链接
    </span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="https://gitee.com/kasnars" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont reco-mayun"></i>
  Gitee
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://juejin.cn/user/2287450072292567" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont reco-juejin"></i>
  稀土掘金
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div> <!----></nav></div></header> <div class="sidebar-mask" data-v-1aefc0b4></div> <aside class="sidebar" data-v-1aefc0b4><div class="personal-info-wrapper" data-v-39576ba9 data-v-1aefc0b4><img src="/markdown-blog/wsqgif.gif" alt="author-avatar" class="personal-img" data-v-39576ba9> <h3 class="name" data-v-39576ba9>
    kasnars
  </h3> <div class="num" data-v-39576ba9><div data-v-39576ba9><h3 data-v-39576ba9>21</h3> <h6 data-v-39576ba9>Articles</h6></div> <div data-v-39576ba9><h3 data-v-39576ba9>14</h3> <h6 data-v-39576ba9>Tags</h6></div></div> <ul class="social-links" data-v-39576ba9></ul> <hr data-v-39576ba9></div> <nav class="nav-links"><div class="nav-item"><a href="/markdown-blog/" class="nav-link"><i class="iconfont reco-home"></i>
  主页
</a></div><div class="nav-item"><a href="/markdown-blog/timeline/" class="nav-link"><i class="iconfont reco-date"></i>
  时间轴
</a></div><div class="nav-item"><a href="/markdown-blog/tag/" class="nav-link"><i class="iconfont reco-tag"></i>
  标签
</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title"><i class="iconfont reco-message"></i>
      文档
    </span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/markdown-blog/docs/theme-reco/" class="nav-link router-link-active"><i class="undefined"></i>
  前端知识点
</a></li><li class="dropdown-item"><!----> <a href="/markdown-blog/docs/computer/" class="nav-link"><i class="undefined"></i>
  计算机基础
</a></li><li class="dropdown-item"><!----> <a href="/markdown-blog/docs/others/" class="nav-link"><i class="undefined"></i>
  其他技术栈
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title"><i class="iconfont reco-category"></i>
      分类
    </span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/markdown-blog/categories/个人作品/" class="nav-link"><i class="undefined"></i>
  个人作品
</a></li><li class="dropdown-item"><!----> <a href="/markdown-blog/categories/解决方案/" class="nav-link"><i class="undefined"></i>
  解决方案
</a></li><li class="dropdown-item"><!----> <a href="/markdown-blog/categories/BUG记录/" class="nav-link"><i class="undefined"></i>
  BUG记录
</a></li><li class="dropdown-item"><!----> <a href="/markdown-blog/categories/技术整理/" class="nav-link"><i class="undefined"></i>
  技术整理
</a></li><li class="dropdown-item"><!----> <a href="/markdown-blog/categories/前端总结/" class="nav-link"><i class="undefined"></i>
  前端总结
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title"><i class="iconfont reco-message"></i>
      链接
    </span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="https://gitee.com/kasnars" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont reco-mayun"></i>
  Gitee
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://juejin.cn/user/2287450072292567" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont reco-juejin"></i>
  稀土掘金
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div> <!----></nav> <ul class="sidebar-links"><li><a href="/markdown-blog/docs/theme-reco/htmlcss.html" class="sidebar-link">HTML+CSS知识点总结</a></li><li><a href="/markdown-blog/docs/theme-reco/js.html" class="sidebar-link">JavaScript知识点总结</a></li><li><a href="/markdown-blog/docs/theme-reco/ts.html" class="sidebar-link">TypeScript知识点总结</a></li><li><a href="/markdown-blog/docs/theme-reco/vue.html" aria-current="page" class="active sidebar-link">Vue知识点总结</a></li><li><a href="/markdown-blog/docs/theme-reco/react.html" class="sidebar-link">React知识点总结</a></li></ul> </aside> <div class="password-shadow password-wrapper-in" style="display:none;" data-v-25ba6db2 data-v-1aefc0b4><h3 class="title" data-v-25ba6db2 data-v-25ba6db2>Vue知识点总结</h3> <!----> <label id="box" class="inputBox" data-v-25ba6db2 data-v-25ba6db2><input type="password" value="" data-v-25ba6db2> <span data-v-25ba6db2>Konck! Knock!</span> <button data-v-25ba6db2>OK</button></label> <div class="footer" data-v-25ba6db2 data-v-25ba6db2><span data-v-25ba6db2><i class="iconfont reco-theme" data-v-25ba6db2></i> <a target="blank" href="https://vuepress-theme-reco.recoluan.com" data-v-25ba6db2>vuePress-theme-reco</a></span> <span data-v-25ba6db2><i class="iconfont reco-copyright" data-v-25ba6db2></i> <a data-v-25ba6db2><span data-v-25ba6db2>kasnars</span>
            
          <span data-v-25ba6db2>2021 - </span>
          2024
        </a></span></div></div> <div data-v-1aefc0b4><main class="page" style="padding-right:0;"><section><div class="page-title"><h1 class="title">Vue知识点总结</h1> <div data-v-f875f3fc><i class="iconfont reco-account" data-v-f875f3fc><span data-v-f875f3fc>kasnars</span></i> <i class="iconfont reco-date" data-v-f875f3fc><span data-v-f875f3fc>2/8/2022</span></i> <i class="iconfont reco-eye" data-v-f875f3fc><span id="/markdown-blog/docs/theme-reco/vue.html" data-flag-title="Your Article Title" class="leancloud-visitors" data-v-f875f3fc><a class="leancloud-visitors-count" style="font-size:.9rem;font-weight:normal;color:#999;"></a></span></i> <i class="tags iconfont reco-tag" data-v-f875f3fc><span class="tag-item" data-v-f875f3fc>Vue</span><span class="tag-item" data-v-f875f3fc>面经</span></i></div></div> <div class="theme-reco-content content__default"><h1 id="vue知识点总结"><a href="#vue知识点总结" class="header-anchor">#</a> Vue知识点总结</h1> <h2 id="vue概念相关"><a href="#vue概念相关" class="header-anchor">#</a> vue概念相关</h2> <h3 id="vue和react-angular的相同处"><a href="#vue和react-angular的相同处" class="header-anchor">#</a> vue和react，angular的相同处</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>Vue 借鉴了 angular 的模板和数据绑定技术，又借鉴了 react 的组件化和虚拟 DOM 技术</li></ul></details> <h3 id="谈谈对vue的理解"><a href="#谈谈对vue的理解" class="header-anchor">#</a> 谈谈对vue的理解</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>渐进式 JavaScript 框架、核心库加插件、动态创建用户界面（异步获取后台数据，数据展示在界面）</li> <li>MVVM 模式；代码简洁体积小，运行效率高，适合移动PC端开发；本身只关注 UI （和 react 相似），可以轻松引入 Vue 插件或其他的第三方库进行开发</li></ul></details> <h3 id="mvvm是什么"><a href="#mvvm是什么" class="header-anchor">#</a> MVVM是什么</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>Model-View-ViewModel ， Model 表示数据模型层。 view 表示视图层， ViewModel 是 View 和 Model 层的桥梁，数据绑定到 viewModel 层并自动渲染到页面中，视图变化通知 viewModel 层更新数据。</li></ul></details> <h2 id="vue基础"><a href="#vue基础" class="header-anchor">#</a> vue基础</h2> <div class="custom-block tip"><p class="title"></p><p>该部分为vue基础使用部分，如果不能回答出80%左右证明vue还不够熟悉</p></div><h3 id="vue有哪些生命周期"><a href="#vue有哪些生命周期" class="header-anchor">#</a> vue有哪些生命周期</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>beforeCreate ：实例初始化之后，数据观测之前调用</li> <li>created：实例创建完之后调用。实例完成：数据观测、属性和方法的运算、 watch/event 事件回调。无 $el .</li> <li>beforeMount：在挂载之前调用，相关 render 函数首次被调用</li> <li>mounted：数据挂载了并被新创建的vm.$el替换，并挂载到实例上去之后调用该钩子。</li> <li>beforeUpdate：数据更新前调用，发生在虚拟DOM重新渲染和打补丁，在这之后会调用该钩子。</li> <li>updated：由于数据更改导致的虚拟DOM重新渲染和打补丁，在这之后会调用该钩子。</li> <li>beforeDestroy：实例销毁前调用，实例仍然可用。</li> <li>destroyed：实例销毁之后调用，调用后，Vue实例指示的所有东西都会解绑，所有事件监听器和所有子实例都会被移除</li></ul></details> <h3 id="vue哪些生命周期常用-分别拿来干什么"><a href="#vue哪些生命周期常用-分别拿来干什么" class="header-anchor">#</a> vue哪些生命周期常用，分别拿来干什么</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>created：实例已经创建完成，因为他是最早触发的，所以可以进行一些数据、资源的请求。(但一般不在这里发送网络请求，具体见下题)</li> <li>mounted：实例已经挂载完成，可以进行一些DOM操作，网络请求等。</li> <li>beforeUpdate：可以在这个钩子中进一步的更改状态，不会触发重渲染。</li> <li>updated：可以执行依赖于DOM的操作，但是要避免更改状态，可能会导致更新无线循环！！！</li> <li>destroyed：可以执行一些优化操作，清空计时器，解除绑定事件。</li></ul></details> <h3 id="keep-alive-是什么"><a href="#keep-alive-是什么" class="header-anchor">#</a> keep-alive 是什么</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>把切换出去的组件保留在内存中，可以保留它的状态或避免重新渲染。用作缓存当前组件。</li> <li>activated keep-alive组件激活时调用，该钩子在服务器端渲染期间不被调用。</li> <li>deactivated keep-alive组件停用时调用，该钩子在服务端渲染期间不被调用。</li></ul></details> <h3 id="keep-alive对生命周期的影响"><a href="#keep-alive对生命周期的影响" class="header-anchor">#</a> keep-alive对生命周期的影响</h3> <details class="custom-block details"><summary>答案</summary> <p>新增两个keep-alive自身的生命周期</p> <ul><li>activated keep-alive组件激活时调用，该钩子在服务器端渲染期间不被调用。</li> <li>deactivated keep-alive组件停用时调用，该钩子在服务端渲染期间不被调用。</li></ul></details> <h3 id="网络请求放在哪个生命周期-为什么"><a href="#网络请求放在哪个生命周期-为什么" class="header-anchor">#</a> 网络请求放在哪个生命周期，为什么</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>一般放在 mounted 中，保证逻辑统一性，因为生命周期是同步执行的， ajax 是异步执行的。</li> <li>但服务端渲染时 （ssr） 统一放在 created 中，因为服务端渲染不支持 mounted 方法</li></ul></details> <h3 id="什么时候使用beforedestory"><a href="#什么时候使用beforedestory" class="header-anchor">#</a> 什么时候使用beforeDestory</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>当前页面使用 $on ，需要解绑事件。清楚定时器。解除事件绑定， scroll mousemove 。</li></ul></details> <h3 id="父子组件生命周期调用顺序"><a href="#父子组件生命周期调用顺序" class="header-anchor">#</a> 父子组件生命周期调用顺序</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>渲染顺序：先父后子，完成顺序：先子后父</li> <li>更新顺序：父更新导致子更新，子更新完成后父</li> <li>销毁顺序：先父后子，完成顺序：先子后父</li> <li><strong>熟悉koa的可以联想洋葱圈模型</strong></li></ul></details> <h3 id="父子组件通信的方法"><a href="#父子组件通信的方法" class="header-anchor">#</a> 父子组件通信的方法</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>父亲提供数据通过属性 props传给儿子；儿子通过 $on 绑父亲的事件，再通过 $emit 触发自己的事件（发布订阅）</li> <li>利用父子关系 $parent 、 $children</li> <li>父组件提供数据，子组件注入。 provide 、 inject ，插件用得多</li> <li>ref 获取组件实例，调用组件的属性、方法</li> <li>跨组件通信 Event Bus （Vue.prototype.bus = new Vue）其实基于bus=newVue）其实基于on与$emit</li> <li>vuex 状态管理实现通信</li></ul></details> <h3 id="vue3中所新增的父子通信方法"><a href="#vue3中所新增的父子通信方法" class="header-anchor">#</a> VUE3中所新增的父子通信方法</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>provide，inject</li> <li>父组件用provide提供数据，子组件用inject接收</li></ul></details> <h3 id="computed-和-watch对比"><a href="#computed-和-watch对比" class="header-anchor">#</a> computed 和 watch对比</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>computed：默认computed也是一个watcher具备缓存，只有当依赖的数据变化时才会计算, 当数据没有变化时, 它会读取缓存数据。如果一个数据依赖于其他数据，使用 computed。</li> <li>每次都需要执行函数。 watch 更适用于数据变化时的异步操作。如果需要在某个数据变化时做一些事情，使用watch。</li></ul></details> <h3 id="v-if和v-show的区别"><a href="#v-if和v-show的区别" class="header-anchor">#</a> v-if和v-show的区别</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>v-if 如果条件不成立不会渲染当前指令所在节点的DOM元素。</li> <li>v-show 只是切换当前DOM的显示与隐藏(dom已经被渲染了)。</li> <li>需要频繁切换的时候用v-show，很少切换或者仅仅做逻辑判断用v-for，减少没必要的重复渲染，提升性能</li></ul></details> <h3 id="v-for和v-if为什么不能连用"><a href="#v-for和v-if为什么不能连用" class="header-anchor">#</a> v-for和v-if为什么不能连用</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>v-for 会比 v-if 的优先级更高，连用的话会把 v-if 的每个元素都添加一下，造成性能问题。</li></ul> <ul><li>tips:关于v-for与v-if谁的优先级更高网上众说纷纭，但是这两个优先级确实有区别</li></ul></details> <h3 id="v-html-会导致哪些问题"><a href="#v-html-会导致哪些问题" class="header-anchor">#</a> v-html 会导致哪些问题</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>XSS攻击</li> <li>v-html 会替换标签内部的元素</li></ul></details> <h3 id="为什么vue里的data是一个函数"><a href="#为什么vue里的data是一个函数" class="header-anchor">#</a> 为什么vue里的data是一个函数</h3> <details class="custom-block details"><summary>答案</summary> <p>避免组件中的数据互相影响。同一个组件被复用多次会创建多个实例，如果 data 是一个对象的话，这些实例用的是同一个构造函数。为了保证组件的数据独立，要求每个组件都必须通过 data 函数返回一个对象作为组件的状态。</p></details> <h3 id="为什么要使用异步组件"><a href="#为什么要使用异步组件" class="header-anchor">#</a> 为什么要使用异步组件</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>节省打包出的结果，异步组件分开打包，采用jsonp的方式进行加载，有效解决文件过大的问题。</li> <li>核心就是包组件定义变成一个函数，依赖 import（） 语法，可以实现文件的分割加载。</li></ul></details> <h3 id="action和mutation的区别"><a href="#action和mutation的区别" class="header-anchor">#</a> action和mutation的区别</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>mutation 是同步更新， $watch 严格模式下会报错</li> <li>action 是异步操作，可以获取数据后调用 mutation 提交最终数据</li></ul></details> <h3 id="插槽是什么"><a href="#插槽是什么" class="header-anchor">#</a> 插槽是什么</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>创建组件虚拟节点时，会将组件儿子的虚拟节点保存起来。当初始化组件时，通过插槽属性将儿子进行分类 {a:[vnode],b[vnode]}</li> <li>渲染组件时会拿对应的 slot 属性的节点进行替换操作。（插槽的作用域为父组件）</li></ul></details> <h3 id="作用域插槽是什么"><a href="#作用域插槽是什么" class="header-anchor">#</a> 作用域插槽是什么</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>作用域插槽在解析的时候不会作为组件的孩子节点。会解析成函数，当子组件渲染时，会调用此函数进行渲染。</li> <li>普通插槽渲染的作用域是父组件，作用域插槽的渲染作用域是当前子组件。</li></ul></details> <h3 id="vue中相同逻辑如何抽离"><a href="#vue中相同逻辑如何抽离" class="header-anchor">#</a> vue中相同逻辑如何抽离</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>vue.mixin方法（vue2）</li> <li>但是mixin并不好，有很多的副作用，比如重名冲突等</li></ul></details> <h3 id="vue性能优化"><a href="#vue性能优化" class="header-anchor">#</a> vue性能优化</h3> <details class="custom-block details"><summary>答案</summary> <p>四个方面：代码层面，用户体验层面，vue自身，浏览器层面</p> <ol><li>代码
<ul><li>事件代理</li> <li>keep-alive</li> <li>拆分组件</li> <li>key 保证唯一性</li> <li>路由懒加载、异步组件</li> <li>防抖节流</li></ul></li> <li>用户
<ul><li>app-skeleton 骨架屏</li> <li>pwa</li></ul></li> <li>vue框架打包加载等
<ul><li>第三方模块按需导入（ babel-plugin-component ）</li> <li>图片懒加载</li></ul></li> <li>浏览器
<ul><li>seo优化，预渲染</li></ul></li></ol></details> <h2 id="vue原理"><a href="#vue原理" class="header-anchor">#</a> vue原理</h2> <h3 id="vue2如何实现响应式数据-响应式数据原理"><a href="#vue2如何实现响应式数据-响应式数据原理" class="header-anchor">#</a> vue2如何实现响应式数据(响应式数据原理)</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>利用Object.defineProperty 重新定义 data 中所有的属性， Object.defineProperty 可以使数据的获取与设置增加一个拦截的功能，拦截属性的获取，进行依赖收集。拦截属性的更新操作，进行通知。</li> <li>具体过程(进阶):首先Vue使用 initData 初始化用户传入的参数，然后使用  new Observer 对数据进行观测，如果数据是一个对象类型就会调用 this.walk（value） 对对象进行处理，内部使用  defineeReactive  循环对象属性定义响应式变化，核心就是使用 Object.defineProperty 重新定义数据。</li></ul></details> <h3 id="vue如何监听数组变化"><a href="#vue如何监听数组变化" class="header-anchor">#</a> vue如何监听数组变化</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>是用来函数劫持的方式，重写了数组方法（pop 、 push 、 shift 、 unshift 、 splice 、 sort 、 reverse），具体呢就是更改了数组的原型，更改成自己的，用户调数组的一些方法的时候，走的就是自己的方法，然后通知视图去更新。</li> <li>数组里每一项可能是对象，那么我就是会对数组的每一项进行观测，（且只有数组里的对象才能进行观测，观测过的也不会进行观测）</li> <li>vue3：改用 proxy ，可直接监听对象数组的变化。</li></ul></details> <h3 id="描述组件渲染和更新的过程"><a href="#描述组件渲染和更新的过程" class="header-anchor">#</a> 描述组件渲染和更新的过程</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>渲染组件时，会通过 vue.extend() 方法构建子组件的构造函数，并进行实例化。最终手动调用 $mount() 进行挂载。</li> <li>更新组件时会进行 patchVnode 流程，核心就是 diff 算法。</li></ul></details> <h3 id="vue事件绑定原理"><a href="#vue事件绑定原理" class="header-anchor">#</a> vue事件绑定原理</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>原生 DOM 的绑定：Vue在创建真实DOM时会调用 createElm ，默认会调用 invokeCreateHooks 。会遍历当前平台下相对的属性处理代码，其中就有 updateDOMListeners 方法，内部会传入 add（） 方法</li> <li>组件绑定事件，原生事件，自定义事件：组件绑定之间是通过Vue中自定义的 $on 方法实现的。</li></ul></details> <h3 id="v-model的原理"><a href="#v-model的原理" class="header-anchor">#</a> v-model的原理</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>v-model 可以看成是 value+input 方法的语法糖（组件）。原生的 v-model ，会根据标签的不同生成不同的事件与属性。解析一个指令来。</li> <li>自己实现v-model：自己写 model 属性，里面放上 prop 和 event</li></ul></details> <h3 id="vue渲染是异步还是同步-为什么"><a href="#vue渲染是异步还是同步-为什么" class="header-anchor">#</a> vue渲染是异步还是同步，为什么？</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>vue是组件级更新，如果不采用异步更新的话，每次其中一部分改变都会导致整个大组件重新渲染，影响性能，所以vue会在本轮更新结束后异步更新视图，核心思想是nextTick</li> <li>自己实现v-model：自己写 model 属性，里面放上 prop 和 event</li> <li>异步更新原理(进阶): 通知 watcher进行更新， subs[i].update 依次调用 watcher 的 update ， queueWatcher 将watcher 去重放入队列， nextTick（ flushSchedulerQueue ）在下一tick中刷新watcher队列（异步）</li></ul></details> <h3 id="谈谈-nexttick"><a href="#谈谈-nexttick" class="header-anchor">#</a> 谈谈$nextTick</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>用于异步获取dom节点 原因是因为vue异步渲染</li> <li>异步方法，异步渲染最后一步，与JS事件循环联系紧密。主要使用了宏任务微任务（setTimeout、promise那些），定义了一个异步方法，多次调用nextTick会将方法存入队列，通过异步方法清空当前队列。</li></ul></details> <h3 id="vuex-是什么-并且谈谈工作原理-有什么用"><a href="#vuex-是什么-并且谈谈工作原理-有什么用" class="header-anchor">#</a> Vuex 是什么？并且谈谈工作原理？有什么用？</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>vuex是一个专为vue打造的状态管理模式</li> <li>vuex组成：
<ul><li>state：state是存储的单一状态，是存储的基本数据。</li> <li>Getters：getters是store的计算属性，对state的加工，是派生出来的数据。</li> <li>Mutations： mutations提交更改数据，使用store.commit方法更改state存储的状态。（mutations同步函数）。</li> <li>Actions：actions像一个装饰器，提交mutation，而不是直接变更状态。（actions可以包含任何异步操作）。</li> <li>Module： Module是store分割的模块，每个模块拥有自己的state、getters、mutations、actions。</li></ul></li> <li>为什么要用vuex？：
<ul><li>vuex，多组件共享状态。</li> <li>多个视图依赖于同一状态。</li> <li>来自不同视图的行为需要变更同一状态。</li></ul></li></ul></details> <h3 id="如何从虚拟dom转化为真实dom"><a href="#如何从虚拟dom转化为真实dom" class="header-anchor">#</a> 如何从虚拟dom转化为真实dom</h3> <details class="custom-block details"><summary>答案</summary> <p>涉及到Vue中的模板编译原理，主要过程：</p> <ol><li>将模板转换成 ast 树， ast 用对象来描述真实的JS语法（将真实DOM转换成虚拟DOM）</li> <li>优化树</li> <li>将 ast 树生成代码</li></ol></details> <h3 id="什么是vnode-vnode如何描述dom结构"><a href="#什么是vnode-vnode如何描述dom结构" class="header-anchor">#</a> 什么是vnode？vnode如何描述dom结构</h3> <details class="custom-block details"><summary>答案</summary> <p>虚拟节点就是用一个对象来描述一个真实的DOM元素。首先将 template （真实DOM）先转成 ast ， ast 树通过 codegen 生成 render 函数， render 函数里的 _c 方法将它转为虚拟dom</p> <ul><li>template -&gt; ast -&gt; render -&gt; dom</li></ul></details> <h3 id="手写一段vnode-进阶"><a href="#手写一段vnode-进阶" class="header-anchor">#</a> 手写一段vnode(进阶)</h3> <details class="custom-block details"><summary>答案</summary> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">// real dom</span>
<span class="token operator">&lt;</span>div id<span class="token operator">=</span><span class="token string">&quot;container&quot;</span><span class="token operator">&gt;</span><span class="token operator">&lt;</span>p<span class="token operator">&gt;</span><span class="token operator">&lt;</span><span class="token operator">/</span>p<span class="token operator">&gt;</span><span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span>
<span class="token comment">// 下面就描述了上面的dom</span>

<span class="token comment">// vnode</span>
<span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token literal-property property">tag</span><span class="token operator">:</span> <span class="token string">'div'</span><span class="token punctuation">,</span>
  <span class="token literal-property property">data</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token string">'container'</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token literal-property property">children</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">{</span>
    <span class="token literal-property property">tag</span><span class="token operator">:</span> <span class="token string">'p'</span><span class="token punctuation">,</span>
    <span class="token literal-property property">data</span><span class="token operator">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token literal-property property">children</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
  <span class="token punctuation">}</span><span class="token punctuation">]</span>
<span class="token punctuation">}</span>

<span class="token comment">// render</span>
<span class="token function">render</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token function">_c</span><span class="token punctuation">(</span><span class="token string">'div'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token string">'container'</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function">_c</span><span class="token punctuation">(</span><span class="token string">'p'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br></div></div></details> <h3 id="diff算法的时间复杂度"><a href="#diff算法的时间复杂度" class="header-anchor">#</a> diff算法的时间复杂度</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>O(n)</li></ul> <p>个树的完全 diff 算法是一个时间复杂度为 O(n*3） ，vue进行优化转化成 O(n) 。</p></details> <h3 id="对vue中diff的理解以及运作方式"><a href="#对vue中diff的理解以及运作方式" class="header-anchor">#</a> 对vue中diff的理解以及运作方式</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>最小量更新， key 很重要。这个可以是这个节点的唯一标识，告诉 diff 算法，在更改前后它们是同一个DOM节点 （v-for需要key的原因）</li> <li>只有是同一个虚拟节点才会进行精细化比较，否则就是暴力删除旧的，插入新的。</li> <li>只进行同层比较，不会进行跨层比较。</li></ul></details> <h3 id="diff算法的优化策略-进阶"><a href="#diff算法的优化策略-进阶" class="header-anchor">#</a> diff算法的优化策略(进阶)</h3> <details class="custom-block details"><summary>答案</summary> <p>四种命中查找，四个指针</p> <ul><li>旧前与新前（先比开头，后插入和删除节点的这种情况）</li> <li>旧后与新后（比结尾，前插入或删除的情况）</li> <li>旧前与新后（头与尾比，此种发生了，涉及移动节点，那么新前指向的节点，移动到旧后之后）</li> <li>旧后与新前（尾与头比，此种发生了，涉及移动节点，那么新前指向的节点，移动到旧前之前）</li></ul></details> <p><em>该页面数据由本人编写+网上论坛整理所得</em></p> <p><em>参考数据地址</em></p> <ul><li><a href="https://juejin.cn/post/6930897845369356295" target="_blank" rel="noopener noreferrer">化身面试官出30+Vue面试题，超级干货（附答案）｜牛气冲天新年征文<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></section> <footer class="page-edit"><!----> <div class="last-updated"><span class="prefix">Last Updated: </span> <span class="time">2/28/2024, 10:12:15 PM</span></div></footer> <div class="page-nav"><p class="inner"><span class="prev"><a href="/markdown-blog/docs/theme-reco/ts.html" class="prev">
            TypeScript知识点总结
          </a></span> <span class="next"><a href="/markdown-blog/docs/theme-reco/react.html">
            React知识点总结
          </a></span></p></div> <div class="comments-wrapper"><!----></div> <ul class="side-bar sub-sidebar-wrapper" style="width:0;" data-v-cb1513f6></ul></main> <!----></div></div></div></div><div class="global-ui"><div class="back-to-ceiling" style="right:1rem;bottom:6rem;width:2.5rem;height:2.5rem;border-radius:.25rem;line-height:2.5rem;display:none;" data-v-c6073ba8 data-v-c6073ba8><svg t="1574745035067" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5404" class="icon" data-v-c6073ba8><path d="M526.60727968 10.90185116a27.675 27.675 0 0 0-29.21455937 0c-131.36607665 82.28402758-218.69155461 228.01873535-218.69155402 394.07834331a462.20625001 462.20625001 0 0 0 5.36959153 69.94390903c1.00431239 6.55289093-0.34802892 13.13561351-3.76865779 18.80351572-32.63518765 54.11355614-51.75690182 118.55860487-51.7569018 187.94566865a371.06718723 371.06718723 0 0 0 11.50484808 91.98906777c6.53300375 25.50556257 41.68394495 28.14064038 52.69160883 4.22606766 17.37162448-37.73630017 42.14135425-72.50938081 72.80769204-103.21549295 2.18761121 3.04276886 4.15646224 6.24463696 6.40373557 9.22774369a1871.4375 1871.4375 0 0 0 140.04691725 5.34970492 1866.36093723 1866.36093723 0 0 0 140.04691723-5.34970492c2.24727335-2.98310674 4.21612437-6.18497483 6.3937923-9.2178004 30.66633723 30.70611158 55.4360664 65.4791928 72.80769147 103.21549355 11.00766384 23.91457269 46.15860503 21.27949489 52.69160879-4.22606768a371.15156223 371.15156223 0 0 0 11.514792-91.99901164c0-69.36717486-19.13165746-133.82216804-51.75690182-187.92578088-3.42062944-5.66790279-4.76302748-12.26056868-3.76865837-18.80351632a462.20625001 462.20625001 0 0 0 5.36959269-69.943909c-0.00994388-166.08943902-87.32547796-311.81420293-218.6915546-394.09823051zM605.93803103 357.87693858a93.93749974 93.93749974 0 1 1-187.89594924 6.1e-7 93.93749974 93.93749974 0 0 1 187.89594924-6.1e-7z" p-id="5405" data-v-c6073ba8></path><path d="M429.50777625 765.63860547C429.50777625 803.39355007 466.44236686 1000.39046097 512.00932183 1000.39046097c45.56695499 0 82.4922232-197.00623328 82.5015456-234.7518555 0-37.75494459-36.9345906-68.35043303-82.4922232-68.34111062-45.57627738-0.00932239-82.52019037 30.59548842-82.51086798 68.34111062z" p-id="5406" data-v-c6073ba8></path></svg></div></div></div>
    <script src="/markdown-blog/assets/js/app.4ad08097.js" defer></script><script src="/markdown-blog/assets/js/3.ddd67056.js" defer></script><script src="/markdown-blog/assets/js/1.7a25059f.js" defer></script><script src="/markdown-blog/assets/js/31.3a6f1d19.js" defer></script>
  </body>
</html>
